package com.wus.gateway.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONUtil;
import com.wus.common.core.constant.cache.CacheConstants;
import com.wus.common.core.domain.base.Result;
import com.wus.common.core.domain.user.AccountInfo;
import com.wus.common.core.exception.BusinessException;
import com.wus.gateway.service.UserService;
import com.wus.gateway.util.JwtUtils;
import com.wus.system.api.SystemApiService;
import com.wus.system.request.LoginUserReq;
import com.wus.system.response.LoginUserResp;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * @Description: 用户操作实现类
 * @Author: wus
 * @Date: 2024/12/17 20:57
 */
@RequiredArgsConstructor
@Service
public class UserServiceImpl implements UserService {

    private final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    private final RedisTemplate<String, Object> redisTemplate;
    private final SystemApiService systemApiService;
    private final JwtUtils jwtUtils;

    @Override
    public LoginUserResp login(LoginUserReq req) {
        Result<AccountInfo> result = systemApiService.login(req);
        if (result.getCode() != 200) {
            throw BusinessException.newInstance(result.getMsg());
        }
        AccountInfo accountInfo = result.getData();

        // 非jwt情况下，value则存用户具体信息。其中uuid是登录生成的token
        /*String cacheKey = String.format(CacheConstants.CACHE_LOGIN_USER_INFO_KEY, accountInfo.getUserId(), uuid);
        redisTemplate.opsForValue().set(cacheKey, JSONUtil.toJsonStr(accountInfo));*/

        // 缓存到redis中，jwt方式下，value不需存用户具体信息，只存登录标识(saToken框架已存);
        // --这里采用saToken + jwt方式, jwt主要是避免网关重复查询mysql或redis缓存
        StpUtil.login(accountInfo.getUserId());
        logger.info("登录成功！");
        // 登录标识，前端请求头对应 token
        accountInfo.setLoginToken(StpUtil.getTokenValue());

        LoginUserResp resp = new LoginUserResp();
        BeanUtils.copyProperties(accountInfo, resp);
        // 额外header参数，避免数据库重复查耗时；后续用户信息更新的话，前端调另一个接口刷新jwt（jwt不用设置过期）的旧值即可
        // 用户jwt token, 前端对应 jwtToken
        resp.setJwtToken(jwtUtils.createToken(accountInfo));
        return resp;
    }

    @Override
    public Boolean logout() {
        StpUtil.logout();
        return Boolean.TRUE;
    }
}
